package com.itheima.synchronized_demo2;

/*
    同步方法：就是把synchronized关键字加到方法上

    格式：修饰符 synchronized 返回值类型 方法名(方法参数) {    }

    同步代码块和同步方法的区别:
        1 同步代码块可以锁住指定代码,同步方法是锁住方法中所有代码
        2 同步代码块可以指定锁对象,同步方法不能指定锁对象

    注意 : 同步方法时不能指定锁对象的 , 但是有默认存在的锁对象的。
        1 对于非static方法,同步锁就是this。
        2 对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。   Class类型的对象

 */
public class Ticket implements Runnable {
    private static int ticketCount = 100; // 一共有一百张票

    @Override
    public void run() {
        while (true) {// 循环卖票
            // t1 t2 t3
            // if ( boolean类型的值 ){
            if (method()) {
                break;
            }
        }
        // 模拟出票的时间
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

//    /*
//        非静态的同步方法 : 不能指定锁对象 , 默认锁对象this
//     */
//    public synchronized boolean method() {
//        // 如果票的数量为0 , 那么停止买票
//        if (ticketCount <= 0) {
//            return true;
//        }
//
//        // 有剩余的票 , 开始卖票
//        ticketCount--;
//        System.out.println(Thread.currentThread().getName() + "卖出一张票,剩下" + ticketCount + "张");
//        return false;
//    }
    /*
         静态的同步方法 : 不能指定锁对象 , 默认锁对象当前类的字节码对象(.class对象)
         同一个类的字节码对象唯一!
    */
    public static synchronized boolean method() {
        // 如果票的数量为0 , 那么停止买票
        if (ticketCount <= 0) {
            return true;
        }

        // 有剩余的票 , 开始卖票
        ticketCount--;
        System.out.println(Thread.currentThread().getName() + "卖出一张票,剩下" + ticketCount + "张");
        return false;
    }
}
